Hanging Chain Problem

We will solve a reformulated version of the Hanging Chain Problem from the Constrained Optimization Problem Set.

Problem Statement and Model

In this problem, we seek to minimize the potential energy of a chain of length $L$ suspended between points $a$ and $b$. The potential energy constrained by length is represented by:

\[\begin{gathered} \int_0^1 x(1 + (x')^2)^{1/2} \, dt \end{gathered}\]

Our optimization problem is defined as follows:

\[\begin{aligned} &&\min_{x,u} x_2(t_f)\\ &&\text{s.t.} &&& \quad \dot{x}_1= u\\ &&&&&\dot{x}_2 = x_1(1+u^2)^{1/2}\\ &&&&&\dot{x}_3 = (1+u^2)^{1/2}\\ &&&&&x(t_0) = (a,0,0)^T\\ &&&&&x_1(t_f) = b\\ &&&&&x_3(t_f) = L\\ &&&&&x(t) \in [0,10]\\ &&&&&u(t) \in [-10,20]\\ \end{aligned}\]

Model Definition

First we must import $InfiniteOpt$ and other packages.

using InfiniteOpt, Ipopt, Plots;

Next we specify an array of initial conditions as well as problem variables.

a, b, L = 1, 3, 4
x0 = [a, 0, 0]
xtf = [b, NaN, L];

We initialize the infinite model and opt to use the Ipopt solver

m = InfiniteModel(Ipopt.Optimizer);

t is specified as $\ t \in [0,1]$. The bounds are arbitrary for this problem:

@infinite_parameter(m, t in [0,1], num_supports = 100);

Now let's specify variables. $u$ is our controller variable.

@variable(m, 0 <= x[1:3] <= 10, Infinite(t))
@variable(m, -10 <= u <= 20, Infinite(t));

Specifying the objective to minimize kinetic energy at the final time:

@objective(m, Min, x[2](1));

Define the ODEs which serve as our system model.

@constraint(m, ∂(x[1],t) == u)
@constraint(m, ∂(x[2],t) == x[1] * (1 + u^2)^(1/2))
@constraint(m, ∂(x[3],t) == (1 + u^2)^(1/2));

Set our inital and final conditions.

@constraint(m, [i in 1:3], x[i](0) == x0[i])
@constraint(m, x[1](1) == xtf[1])
@constraint(m, x[3](1) == xtf[3]);

Problem Solution

Optimize the model:

optimize!(m)
This is Ipopt version 3.14.17, running with linear solver MUMPS 5.7.3.

Number of nonzeros in equality constraint Jacobian...:     1596
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:      400

Total number of variables............................:      700
                     variables with only lower bounds:        0
                variables with lower and upper bounds:      400
                     variables with only upper bounds:        0
Total number of equality constraints.................:      602
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  9.9999900e-03 3.99e+00 1.00e+00  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  8.6845875e-02 1.95e+01 1.61e+04  -1.0 6.57e+01    -  2.56e-03 3.02e-01f  1
   2  1.7965356e-01 1.87e+01 2.25e+04  -1.0 5.31e+01   4.0 3.21e-02 4.23e-02h  1
   3  1.8137048e-01 1.87e+01 2.33e+04  -1.0 4.73e+01   4.4 6.31e-02 6.68e-04h  1
   4  1.8140295e-01 1.87e+01 1.89e+06  -1.0 4.83e+01   4.9 1.26e-01 1.22e-05h  1
   5  1.9254888e-01 1.86e+01 2.48e+06  -1.0 4.81e+01   4.4 2.04e-01 4.17e-03h  1
   6  2.0905429e-01 1.85e+01 3.64e+06  -1.0 4.86e+01   4.8 1.09e-01 6.07e-03h  1
   7  2.2802793e-01 1.84e+01 3.41e+07  -1.0 4.82e+01   5.2 3.59e-01 6.93e-03h  1
   8  2.8201307e-01 1.80e+01 3.06e+07  -1.0 4.62e+01   4.7 1.02e-01 2.02e-02h  1
   9  3.1317553e-01 1.78e+01 3.47e+07  -1.0 4.47e+01   5.2 2.45e-01 1.13e-02h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  3.4723467e-01 1.76e+01 4.07e+07  -1.0 4.39e+01   5.6 5.62e-02 1.22e-02h  1
  11  3.8552094e-01 1.73e+01 6.10e+07  -1.0 4.28e+01   6.0 6.34e-02 1.37e-02h  1
  12  4.0843146e-01 1.72e+01 6.02e+07  -1.0 3.93e+01   5.6 7.08e-03 8.64e-03h  1
  13  4.1028640e-01 1.72e+01 1.02e+08  -1.0 3.99e+01   6.0 6.60e-02 6.60e-04h  1
  14  4.3553508e-01 1.70e+01 3.20e+08  -1.0 4.04e+01   6.4 1.31e-01 8.93e-03h  1
  15  4.5808211e-01 1.69e+01 3.20e+08  -1.0 3.81e+01   5.9 2.79e-02 8.08e-03h  1
  16  4.6870391e-01 1.68e+01 3.89e+08  -1.0 3.84e+01   6.4 7.68e-02 3.74e-03h  1
  17  5.1251695e-01 1.66e+01 5.77e+08  -1.0 3.84e+01   6.8 8.31e-02 1.54e-02f  1
  18  5.2292005e-01 1.65e+01 5.69e+08  -1.0 3.52e+01   6.3 1.53e-02 3.70e-03h  1
  19  5.2697033e-01 1.65e+01 6.03e+08  -1.0 3.63e+01   6.7 6.98e-02 1.42e-03h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20  6.1393774e-01 1.60e+01 7.16e+08  -1.0 3.66e+01   7.2 8.66e-02 3.03e-02f  1
  21  7.3213394e-01 1.53e+01 6.54e+08  -1.0 3.40e+01   7.6 6.77e-03 4.09e-02f  1
  22  8.0635655e-01 1.49e+01 6.80e+08  -1.0 3.09e+01   8.0 4.06e-04 2.55e-02f  1
  23  8.5443045e-01 1.47e+01 1.27e+09  -1.0 2.92e+01   8.4 1.25e-03 1.65e-02f  1
  24  8.5472095e-01 1.47e+01 7.25e+08  -1.0 2.70e+01   8.0 4.02e-02 9.99e-05h  1
  25  9.4924730e-01 1.42e+01 1.17e+09  -1.0 2.79e+01   8.4 7.89e-03 3.24e-02f  1
  26  9.7274767e-01 1.41e+01 1.75e+09  -1.0 2.61e+01   8.8 1.73e-05 8.07e-03f  1
  27  9.7893019e-01 1.41e+01 1.74e+09  -1.0 2.48e+01   8.3 7.44e-02 2.13e-03h  1
  28  1.1355863e+00 1.33e+01 2.81e+09  -1.0 2.54e+01   8.8 2.24e-05 5.39e-02f  1
  29  1.1851152e+00 1.31e+01 5.26e+09  -1.0 2.26e+01   9.2 1.46e-03 1.71e-02f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30  1.1875976e+00 1.31e+01 6.54e+09  -1.0 2.07e+01   8.7 5.75e-02 8.61e-04h  1
  31  1.3495034e+00 1.23e+01 1.76e+10  -1.0 2.16e+01   9.1 1.24e-03 5.62e-02f  1
  32  1.4016517e+00 1.21e+01 4.27e+10  -1.0 1.92e+01   9.6 1.85e-04 1.84e-02f  1
  33  1.7460477e+00 1.06e+01 5.77e+10  -1.0 1.75e+01   9.1 1.05e-02 1.22e-01f  1
  34  1.7872628e+00 1.05e+01 9.82e+10  -1.0 1.38e+01   9.5 1.91e-05 1.53e-02f  1
  35  1.8094359e+00 1.04e+01 1.72e+11  -1.0 1.38e+01   9.9 4.00e-05 8.30e-03f  1
  36  4.4588974e+00 6.90e+00 1.58e+12  -1.0 1.32e+01   9.5 4.08e-06 9.90e-01f  1
  37  4.4745421e+00 6.74e+00 1.56e+12  -1.0 6.33e+00   9.9 2.59e-05 2.30e-02f  1
  38  5.1417859e+00 6.94e+00 1.26e+12  -1.0 5.94e+00   9.4 4.03e-05 9.90e-01f  1
  39  5.1719734e+00 4.63e+00 1.06e+13  -1.0 5.68e+00   8.9 4.41e-06 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  40  5.1832694e+00 3.21e-02 4.22e+09  -1.0 4.15e+00    -  1.28e-02 1.00e+00f  1
  41  5.1788564e+00 5.04e-02 3.35e+07  -1.0 3.22e-01    -  9.90e-01 1.00e+00h  1
  42  5.1788481e+00 7.84e-08 3.38e+05  -1.0 4.09e+00    -  9.90e-01 1.00e+00H  1
  43  5.1788481e+00 3.55e-15 3.37e+03  -1.0 6.69e-08   8.4 9.90e-01 1.00e+00h  1
  44  5.1788481e+00 3.55e-15 3.33e+01  -1.0 3.78e-10   8.0 9.90e-01 1.00e+00h  1
  45  5.1788481e+00 7.11e-15 2.41e+04  -2.5 2.21e-11   7.5 9.98e-01 1.00e+00h  1
  46  5.1788481e+00 3.55e-15 6.85e-04  -2.5 6.62e-11   7.0 1.00e+00 1.00e+00h  1
  47  5.1788481e+00 3.55e-15 3.20e-04  -5.7 9.28e-11   6.5 1.00e+00 1.00e+00h  1
  48  5.1788481e+00 3.55e-15 3.20e-04  -5.7 2.78e-10   6.1 1.00e+00 1.00e+00h  1
  49  5.1788481e+00 3.55e-15 3.20e-04  -5.7 8.35e-10   5.6 1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  50  5.1788481e+00 3.55e-15 3.20e-04  -5.7 2.50e-09   5.1 1.00e+00 1.00e+00h  1
  51  5.1788481e+00 3.55e-15 3.20e-04  -5.7 7.51e-09   4.6 1.00e+00 1.00e+00h  1
  52  5.1788481e+00 3.55e-15 3.20e-04  -5.7 2.25e-08   4.2 1.00e+00 1.00e+00h  1
  53  5.1788481e+00 3.55e-15 3.20e-04  -5.7 6.76e-08   3.7 1.00e+00 1.00e+00h  1
  54  5.1788481e+00 3.55e-15 3.20e-04  -5.7 2.03e-07   3.2 1.00e+00 1.00e+00h  1
  55  5.1788481e+00 1.55e-14 3.20e-04  -5.7 6.09e-07   2.7 1.00e+00 1.00e+00h  1
  56  5.1788481e+00 1.41e-13 3.20e-04  -5.7 1.83e-06   2.2 1.00e+00 1.00e+00h  1
  57  5.1788480e+00 1.27e-12 3.20e-04  -5.7 5.48e-06   1.8 1.00e+00 1.00e+00h  1
  58  5.1788478e+00 1.14e-11 3.20e-04  -5.7 1.64e-05   1.3 1.00e+00 1.00e+00h  1
  59  5.1788472e+00 1.03e-10 3.20e-04  -5.7 4.93e-05   0.8 1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  60  5.1788454e+00 9.23e-10 3.20e-04  -5.7 1.48e-04   0.3 1.00e+00 1.00e+00h  1
  61  5.1788401e+00 8.31e-09 3.20e-04  -5.7 4.44e-04  -0.1 1.00e+00 1.00e+00h  1
  62  5.1788242e+00 7.48e-08 3.20e-04  -5.7 1.33e-03  -0.6 1.00e+00 1.00e+00h  1
  63  5.1787764e+00 6.72e-07 3.20e-04  -5.7 3.99e-03  -1.1 1.00e+00 1.00e+00h  1
  64  5.1786336e+00 6.02e-06 3.20e-04  -5.7 1.20e-02  -1.6 1.00e+00 1.00e+00h  1
  65  5.1782082e+00 5.36e-05 3.18e-04  -5.7 3.57e-02  -2.1 1.00e+00 1.00e+00h  1
  66  5.1769614e+00 4.65e-04 3.15e-04  -5.7 1.06e-01  -2.5 1.00e+00 1.00e+00h  1
  67  5.1734633e+00 3.77e-03 3.05e-04  -5.7 3.08e-01  -3.0 1.00e+00 1.00e+00h  1
  68  5.1647170e+00 2.53e-02 2.79e-04  -5.7 8.45e-01  -3.5 1.00e+00 1.00e+00h  1
  69  5.1477342e+00 4.35e-01 4.38e-03  -5.7 2.07e+00  -4.0 1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  70  5.1417721e+00 3.72e-01 3.75e-03  -5.7 2.30e+01  -4.4 2.47e-01 1.52e-01h  1
  71  5.1377087e+00 2.16e-01 2.18e-03  -5.7 1.88e+00  -4.0 1.00e+00 5.02e-01h  1
  72  5.1361997e+00 2.05e-01 2.08e-03  -5.7 2.00e+01  -4.5 7.16e-01 5.02e-02h  1
  73  5.1336538e+00 9.94e-02 1.00e-03  -5.7 2.07e+00  -4.1 1.00e+00 5.21e-01h  1
  74  5.1330946e+00 9.88e-02 9.99e-04  -5.7 2.07e+02  -4.5 5.45e-02 6.36e-03h  1
  75  5.1307954e+00 4.17e-02 4.08e-04  -5.7 1.98e+00  -4.1 1.00e+00 8.89e-01h  1
  76  5.1302295e+00 9.65e-03 1.57e-04  -5.7 7.68e-01  -3.7 1.00e+00 8.70e-01h  1
  77  5.1293859e+00 2.43e-02 2.12e-04  -5.7 1.78e+00  -4.2 1.00e+00 1.00e+00f  1
  78  5.1287870e+00 6.63e-03 1.32e-04  -5.7 7.20e-01  -3.7 1.00e+00 1.00e+00h  1
  79  5.1284409e+00 9.41e-03 1.47e-04  -5.7 3.65e+00  -4.2 1.00e+00 1.69e-01h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  80  5.1283044e+00 1.90e-03 6.65e-05  -5.7 3.02e-01  -3.8 1.00e+00 8.81e-01h  1
  81  5.1279412e+00 3.28e-02 3.31e-04  -5.7 1.01e+00  -4.3 1.00e+00 1.00e+00h  1
  82  5.1273694e+00 1.07e-01 6.94e-04  -5.7 4.08e+01  -4.7 2.66e-01 7.73e-02h  1
  83  5.1273611e+00 1.06e-01 6.88e-04  -5.7 2.30e+00  -4.3 1.00e+00 1.12e-02h  1
  84  5.1269621e+00 3.07e-03 1.51e-05  -5.7 2.16e+00    -  1.00e+00 1.00e+00f  1
  85  5.1270446e+00 4.86e-06 2.73e-08  -5.7 1.06e-01    -  1.00e+00 1.00e+00h  1
  86  5.1270303e+00 1.32e-05 3.04e-02  -8.6 8.78e-03    -  1.00e+00 1.00e+00h  1
  87  5.1270301e+00 1.66e-09 1.68e-11  -8.6 1.11e-04    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 87

                                   (scaled)                 (unscaled)
Objective...............:   5.1270301228513375e+00    5.1270301228513375e+00
Dual infeasibility......:   1.6799484678272097e-11    1.6799484678272097e-11
Constraint violation....:   1.6636390043345273e-09    1.6636390043345273e-09
Variable bound violation:   3.6669586446530026e-40    3.6669586446530026e-40
Complementarity.........:   2.5155079248684823e-09    2.5155079248684823e-09
Overall NLP error.......:   2.5155079248684823e-09    2.5155079248684823e-09


Number of objective function evaluations             = 89
Number of objective gradient evaluations             = 88
Number of equality constraint evaluations            = 89
Number of inequality constraint evaluations          = 0
Number of equality constraint Jacobian evaluations   = 88
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations             = 87
Total seconds in IPOPT                               = 0.177

EXIT: Optimal Solution Found.

Extract the results.

ts = value(t)
u_opt = value(u)
x1_opt = value(x[1])
x2_opt = value(x[2])
x3_opt = value(x[3])
@show(objective_value(m))
p1 = plot(ts, [x1_opt, x2_opt, x3_opt],
    label=["x1" "x2" "x3"],
    title="State Variables")

p2 = plot(ts, u_opt,
    label="u(t)",
    title="Input")
plot(p1, p2, layout=(2,1), size=(800,600));
objective_value(m) = 5.1270301228513375

Maintenance Tests

These are here to ensure this example stays up to date.

using Test
@test termination_status(m) == MOI.LOCALLY_SOLVED
@test has_values(m)
@test u_opt isa Vector{<:Real}
@test x1_opt isa Vector{<:Real}
Test Passed

This page was generated using Literate.jl.